{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-01-03T01:32:33.936371Z",
     "start_time": "2025-01-03T01:32:30.059612Z"
    }
   },
   "source": [
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "from sklearn.datasets import fetch_california_housing\n",
    "import os\n",
    "\n",
    "os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'"
   ],
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T01:32:33.967899Z",
     "start_time": "2025-01-03T01:32:33.937884Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 立刻下载数据集\n",
    "housing = fetch_california_housing(data_home=\"D:/scikit_learn_data\", download_if_missing=True)"
   ],
   "id": "93b48a3ee6e0176c",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T01:32:33.983884Z",
     "start_time": "2025-01-03T01:32:33.968888Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 获得X数据行数和列数\n",
    "m, n = housing.data.shape\n",
    "print(m, n) # 20640行 8列\n",
    "print(housing.data, housing.target) # 8列特征数据和目标数据\n",
    "print(housing.feature_names) # 8列特征名称"
   ],
   "id": "4ab1bacd7876333a",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20640 8\n",
      "[[   8.3252       41.            6.98412698 ...    2.55555556\n",
      "    37.88       -122.23      ]\n",
      " [   8.3014       21.            6.23813708 ...    2.10984183\n",
      "    37.86       -122.22      ]\n",
      " [   7.2574       52.            8.28813559 ...    2.80225989\n",
      "    37.85       -122.24      ]\n",
      " ...\n",
      " [   1.7          17.            5.20554273 ...    2.3256351\n",
      "    39.43       -121.22      ]\n",
      " [   1.8672       18.            5.32951289 ...    2.12320917\n",
      "    39.43       -121.32      ]\n",
      " [   2.3886       16.            5.25471698 ...    2.61698113\n",
      "    39.37       -121.24      ]] [4.526 3.585 3.521 ... 0.923 0.847 0.894]\n",
      "['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T01:32:33.999883Z",
     "start_time": "2025-01-03T01:32:33.984884Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 这里添加一个额外的bias输入特征(x0=1)到所有的训练数据上面，因为使用的numpy所以会立即执行\n",
    "housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]\n",
    "housing_data_plus_bias"
   ],
   "id": "3934f7c014356e3a",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[   1.        ,    8.3252    ,   41.        , ...,    2.55555556,\n",
       "          37.88      , -122.23      ],\n",
       "       [   1.        ,    8.3014    ,   21.        , ...,    2.10984183,\n",
       "          37.86      , -122.22      ],\n",
       "       [   1.        ,    7.2574    ,   52.        , ...,    2.80225989,\n",
       "          37.85      , -122.24      ],\n",
       "       ...,\n",
       "       [   1.        ,    1.7       ,   17.        , ...,    2.3256351 ,\n",
       "          39.43      , -121.22      ],\n",
       "       [   1.        ,    1.8672    ,   18.        , ...,    2.12320917,\n",
       "          39.43      , -121.32      ],\n",
       "       [   1.        ,    2.3886    ,   16.        , ...,    2.61698113,\n",
       "          39.37      , -121.24      ]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T01:46:24.138519Z",
     "start_time": "2025-01-03T01:46:24.125219Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 创建两个TensorFlow常量节点X和y，去持有数据和标签\n",
    "X = tf.constant(housing_data_plus_bias, dtype=tf.float32, name='X')\n",
    "y = tf.constant(housing.target.reshape(-1, 1), dtype=tf.float32, name='y')\n",
    "display(X)\n",
    "display(y)"
   ],
   "id": "7997d90896102677",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'X_3:0' shape=(20640, 9) dtype=float32>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'y_3:0' shape=(20640, 1) dtype=float32>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T02:42:07.965886Z",
     "start_time": "2025-01-03T02:42:07.958794Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 求X的转置\n",
    "XT = tf.transpose(X)\n",
    "XT"
   ],
   "id": "d3d2ac798b267fb6",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'transpose_3:0' shape=(9, 20640) dtype=float32>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "$$\n",
    "\\theta=(X^TX)^{-1}X^Ty\n",
    "$$"
   ],
   "id": "584c3dd08db17345"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T03:14:27.594231Z",
     "start_time": "2025-01-03T03:14:27.582991Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 使用一些TensorFlow框架提供的矩阵操作去求theta\n",
    "# 解析解一步计算出最优解\n",
    "xt_x = tf.matmul(XT, X) # XT * X\n",
    "xt_x_inverse = tf.matrix_inverse(xt_x) # 求逆\n",
    "xt_x_inverse_xt = tf.matmul(xt_x_inverse, XT) # (XT * X)^-1 * XT\n",
    "theta = tf.matmul(xt_x_inverse_xt, y) # (XT * X)^-1 * XT * y\n",
    "\n",
    "theta\n"
   ],
   "id": "fd642ff2c3c7a226",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor 'MatMul_20:0' shape=(9, 1) dtype=float32>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 24
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T03:14:28.093783Z",
     "start_time": "2025-01-03T03:14:28.072756Z"
    }
   },
   "cell_type": "code",
   "source": [
    "with tf.Session() as sess:\n",
    "    theta_value = sess.run(theta)  # theta.eval()\n",
    "theta_value"
   ],
   "id": "f5da7c5f636cad77",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-3.6786983e+01],\n",
       "       [ 4.3703085e-01],\n",
       "       [ 9.4685089e-03],\n",
       "       [-1.0764918e-01],\n",
       "       [ 6.4608419e-01],\n",
       "       [-3.8850994e-06],\n",
       "       [-3.7904985e-03],\n",
       "       [-4.1972896e-01],\n",
       "       [-4.3274990e-01]], dtype=float32)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 25
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-03T02:55:59.416001Z",
     "start_time": "2025-01-03T02:55:59.412449Z"
    }
   },
   "cell_type": "code",
   "source": "",
   "id": "36fc585fd8564062",
   "outputs": [],
   "execution_count": 18
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "524f3ef025807cae"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
